package offer

import (
	// "bp/cache"
	sqlc "bp/db/sqlc"
	cardDiscount "bp/internal/service/entity/card_discount"
	memberCoupon "bp/internal/service/entity/member_coupon"
	"bp/internal/service/entity/promotion"
	"encoding/json"
)

type OffTrialItemPtrToTrialedItemPtrFunc func(*sqlc.OffTrialItem) *TrialedItem
type OffTrialPtrToTrialedOfferItemPtrFunc func(*sqlc.OffTrial) *TrialedOfferItem

// ConvOffTrialItemPtrToTrialedItemPtr get func of *sqlc.OffTrialItem => *TrialedItem
func (s *OfferComServiceImp) ConvOffTrialItemPtrToTrialedItemPtr() OffTrialItemPtrToTrialedItemPtrFunc {
	return func(ptr *sqlc.OffTrialItem) *TrialedItem {
		if ptr == nil {
			return nil
		}
		return &TrialedItem{
			SceneDetailID:   ptr.SceneDetailID,
			SceneDetailCnt:  ptr.SceneDetailCnt,
			ItemID:     ptr.ItemID,
			ItemSpecID: ptr.ItemSpecID,
			ItemPrice:  ptr.ItemPrice,
			Off:        ptr.Off,
			Cnt:        ptr.Cnt,
		}
	}
}

// MapOffTrialItemPtrsToTrialedItemPtrs []*sqlc.OffTrialItem => []*TrialedItem
func (s *OfferComServiceImp) MapOffTrialItemPtrsToTrialedItemPtrs(list []*sqlc.OffTrialItem, conv OffTrialItemPtrToTrialedItemPtrFunc) []*TrialedItem {
	ptrs := make([]*TrialedItem, len(list))
	for i, entity := range list {
		ptrs[i] = conv(entity)
	}
	return ptrs
}

// ConvOffTrialPtrToTrialedOfferItemPtr get func of *sqlc.OffTrial => *TrialedOfferItem
func (s *OfferComServiceImp) ConvOffTrialPtrToTrialedOfferItemPtr(
	offTrialItemPtrs []*sqlc.OffTrialItem,
) OffTrialPtrToTrialedOfferItemPtrFunc {
	return func(ptr *sqlc.OffTrial) *TrialedOfferItem {
		if ptr == nil {
			return nil
		}
		var trialedInfoPtr *OffItemInfo
		trialedInfoPtr, _ = s.UnMarshalOfferItemTrialInfoToOffItemTrialInfoPtr(ptr.OfferItemTrialInfo)
		return &TrialedOfferItem{
			Off:             ptr.Off,
			OfferType:       ptr.OfferType,
			OfferItemType:   ptr.OfferItemType,
			OfferItemID:     ptr.OfferItemID,
			TrialedInfoPtr:  trialedInfoPtr,
			TrialedItemPtrs: s.MapOffTrialItemPtrsToTrialedItemPtrs(offTrialItemPtrs, s.ConvOffTrialItemPtrToTrialedItemPtr()),
		}
	}
}

// MapOffTrialPtrsToTrialedOfferItemPtrs []*sqlc.OffTrial => []*TrialedOfferItem
func (s *OfferComServiceImp) MapOffTrialPtrsToTrialedOfferItemPtrs(offTrials []*sqlc.OffTrial, offTrialItemPtrs []*sqlc.OffTrialItem) []*TrialedOfferItem {
	ptrs := make([]*TrialedOfferItem, len(offTrials))
	for i, offTrial := range offTrials {
		offTrialItemPtrsOfTheOffTrial := s.entityHub.OffTrialService.FilterOffTrialItemPtrs(offTrialItemPtrs, func(oti *sqlc.OffTrialItem) bool {
			return oti.OffTrialID == offTrial.ID
		})
		ptrs[i] = s.ConvOffTrialPtrToTrialedOfferItemPtr(offTrialItemPtrsOfTheOffTrial)(offTrial)
	}
	return ptrs
}


func (s *OfferComServiceImp) UnMarshalOfferItemTrialInfoToOffItemTrialInfoPtr(offerItemTrialInfoBytes []byte) (ptr *OffItemInfo, err error) {
	ptr = &OffItemInfo{}
	err = json.Unmarshal(offerItemTrialInfoBytes, ptr)
	if err != nil {
		return
	}
	return
}

func (s *OfferComServiceImp) MarshalOfferItemTrialInfoOfPromotion(ptr *sqlc.Promotion) (offerItemTrialInfoBytes []byte, err error) {
	offerItemTrialInfoPtr := &promotion.PromotionOfferItemInfo{
		ID:   ptr.ID,
		Name: ptr.Name,
		Desc: ptr.Desc.String,
	}
	offerItemTrialInfoBytes, err = json.Marshal(offerItemTrialInfoPtr)
	if err != nil {
		return
	}
	return
}

func (s *OfferComServiceImp) MarshalOfferItemTrialInfoOfMemberCoupon(ptr *sqlc.MemberCoupon) (offerItemTrialInfoBytes []byte, err error) {
	offerItemTrialInfoPtr := &memberCoupon.MemberCouponOfferItemInfo{
		Sn:             ptr.Sn,
		MemberCouponID: ptr.ID,
		CouponID:       ptr.CouponID,
		Name:           ptr.Name,
		Desc:           ptr.Desc.String,
	}
	offerItemTrialInfoBytes, err = json.Marshal(offerItemTrialInfoPtr)
	if err != nil {
		return
	}
	return
}

func (s *OfferComServiceImp) UnMarshalOfferItemTrialInfoOfMemberCoupon(offerItemTrialInfoBytes []byte) (ptr *memberCoupon.MemberCouponOfferItemInfo, err error) {
	ptr = &memberCoupon.MemberCouponOfferItemInfo{}
	err = json.Unmarshal(offerItemTrialInfoBytes, ptr)
	if err != nil {
		return
	}
	return
}

func (s *OfferComServiceImp) MarshalOfferItemTrialInfoOfCardDiscount(ptr *sqlc.CardDiscount, memberID int64) (offerItemTrialInfoBytes []byte, err error) {
	offerItemTrialInfoPtr := &cardDiscount.CardDiscountOfferItemInfo{
		ID:        ptr.ID,
		OutCardID: ptr.OutCardID,
		MemberID:  memberID,
		Name:      ptr.Name,
		Desc:      ptr.Desc.String,
	}
	offerItemTrialInfoBytes, err = json.Marshal(offerItemTrialInfoPtr)
	if err != nil {
		return
	}
	return
}
